package gwtgaetools.client;

import gwtgaetools.client.listeners.ListListener;
import gwtgaetools.shared.model.BaseObject;

import java.util.ArrayList;

public class BasicList<T> extends ArrayList<T> implements ListListener<T> {

	/**
	 * 
	 */
	private static final long				serialVersionUID	= 1637801605642536750L;

	protected ArrayList<ListListener<T>>	listeners			= new ArrayList<ListListener<T>>();

	public BasicList<T>						om;
	// private ArrayList<T> values;
	public ItemManager<Integer>				count				= new ItemManager<Integer>();

	public BasicList() {
		om = this;
		// values = new ArrayList<T>();
		count.setItem(0);
	}

	public BasicList(ArrayList<T> al) {
		this();
		add(al);
	}

	public BasicList(BasicList<T> in) {
		setObservedList(in);
	}

	// public ArrayList<T> getValues() {
	// return values;
	// }

	// TODO: Not needed??
	public void setOm(BasicList<T> in) {
		om = in;
	}

	@Override public boolean add(T t) {
		boolean b = super.add(t);
		for (ListListener<T> al : listeners)
			al.add(t);
		// for (int i=0; i<listeners.size(); i++)
		// listeners.get(i).add(t);

		count.setItem(size());
		return b;
	}

	@Override public void add(int index, T t) {
		super.add(index, t);
		for (ListListener<T> al : listeners)
			al.add(index, t);
		// for (int i=0; i<listeners.size(); i++)
		// listeners.get(i).add(index, t);

		count.setItem(size());
	}

	public void registerListener(ListListener<T> al) {
		listeners.add(al);
		int i = 0;
		for (T t : this) {
			al.add(i, t);
			i++;
		}
	}

	@Override public void clear() {
		for (T t : this)

			for (ListListener<T> ll : listeners)
				ll.delete(t);

		// for (int i=0; i<listeners.size(); i++)
		// listeners.get(i).delete(t);

		for (ListListener<T> ll : listeners)
			ll.clear();

		// for (int i=0; i<listeners.size(); i++)
		// listeners.get(i).clear();

		super.clear();
		count.setItem(size());
	}

	@Override public void delete(T t) {
		super.remove(t);
		for (ListListener<T> ll : listeners)
			ll.delete(t);
		// for (int i=0; i<listeners.size(); i++)
		// listeners.get(i).delete(t);
		count.setItem(size());
	}

	public void deregisterListener(ListListener<T> al) {
		for (T t : this) {
			al.delete(t);
		}
		listeners.remove(al);
	}

	public T getById(String id) {
		for (T t : this) {
			if (((BaseObject<?, ?>) t).getId().equals(id)) { return t; }
		}
		return null;
	}

	public void add(ArrayList<T> l) {
		for (T t : l) {
			add(t);
		}
	}

	public void setObservedList(BasicList<T> in) {
		if (om != this) om.deregisterListener(this);
		clear();
		om = in;
		om.registerListener(this);
	}

	@Override public void updateIndex(T t, int i, int prevI) {
		remove(t);
		super.add(i, t);

		for (ListListener<T> l : listeners)
			l.updateIndex(t, i, prevI);

		// for (int j=0; j<listeners.size(); j++)
		// listeners.get(j).updateIndex(t, i, prevI);
	}

}
